package org.springframework.nio.method;

import java.lang.reflect.Method;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

public class HandlerMethod {
	
	private final Object bean;
	private final Method method;
	private final BeanFactory beanFactory;
	
//	private final MethodParameter[] parameters;

	
	public HandlerMethod(Object bean,Method method){
		Assert.notNull(bean, "Bean is required");
		Assert.notNull(method,"Method is required");
		this.bean = bean;
		this.method = method;
		beanFactory = null;
	}

	public HandlerMethod(Object bean,Method method,BeanFactory factory){
		Assert.notNull(bean, "Bean is required");
		Assert.notNull(method,"Method is required");
		Assert.notNull(factory);
		this.bean = bean;
		this.method = method;
		beanFactory = factory;
	}
	
	public HandlerMethod(String beanName,BeanFactory factory ,Method method){
		Assert.notNull(beanName, "beanName is required");
		Assert.notNull(method,"Method is required");
		Assert.notNull(factory);
		Assert.isTrue(factory.containsBean(beanName),"BeanFactory [" + factory + "] does not contain bean [" + beanName + "]");
		this.bean = factory.getBean(beanName);
		this.method = method;
		beanFactory = factory;
	}
	
	public Object getBean() {
		return bean;
	}

	public Method getMethod() {
		return method;
	}

	public BeanFactory getBeanFactory() {
		return beanFactory;
	}

	
	public Class<?> getBeanType() {
		Class<?> clazz = (this.bean instanceof String ?
				this.beanFactory.getType((String) this.bean) : this.bean.getClass());
		return ClassUtils.getUserClass(clazz);
	}

	@Override
	public boolean equals(Object obj) {

		if(this == obj){
			return true;
		}
		if(obj != null && obj instanceof HandlerMethod){
			HandlerMethod handlerMethod = (HandlerMethod) obj;
			return this.bean == handlerMethod.bean && this.method == handlerMethod.method;
		}
		return false;
	}
	
	
	
}
